import { Controller, Post, Body, BadRequestException, Logger } from '@nestjs/common';
import { MpAuthService } from './auth.service';
import { MpAuthLoginDto, MpAuthPhoneDto, MpAuthUpdateUserInfoDto } from './auth.dto';
import { ApiBearerAuth, ApiBody, ApiExcludeEndpoint, ApiOperation, ApiTags } from '@nestjs/swagger';
import { AuthUser } from '~/modules/auth/decorators/auth-user.decorator';
import { ErrorEnum } from '~/constants/error-code.constant';
import { Public } from '~/modules/auth/decorators/public.decorator';
import { AuthTenant } from '~/modules/tenant/tenant.decorator';
import { TenantEntity } from '~/modules/tenant/tenant.entity';
import { ApiTenantHeader } from '~/common/decorators/api-header-tenant.decorator';
import { UserService } from '~/modules/user/user.service';
import { AllowAnon } from '~/modules/auth/decorators/allow-anon.decorator';
import { AuthService } from '~/modules/auth/auth.service';
import { AuthToken } from '~/common/decorators/auth-token.decorator';
import { BusinessException } from '~/common/exceptions/biz.exception';

@ApiTags('Auth - 认证模块')
@ApiBearerAuth()
@Controller('auth')
export class MpAuthController {
  private readonly logger = new Logger(MpAuthController.name);

  constructor(
    private readonly mpAuthService: MpAuthService,
    private readonly userService: UserService,
    private readonly authService: AuthService
  ) {}

  @Public()
  @Post('login')
  @ApiTenantHeader()
  @ApiOperation({ summary: '登录' })
  @ApiBody({ type: MpAuthLoginDto })
  async login(
    @Body() authDto: MpAuthLoginDto,
    @AuthTenant() tenant: TenantEntity
  ): Promise<string> {
    if (!authDto?.code) {
      throw new BadRequestException(ErrorEnum.INVALID_CODE);
    }

    // TODO 排查无租户登录问题
    let tenantId = Number(tenant?.id ?? 1);

    if (!tenantId) {
      throw new BadRequestException(ErrorEnum.INVALID_TENANT);
    }

    return await this.mpAuthService.login(authDto?.code ?? '', tenantId);
  }

  @Post('phone')
  @ApiOperation({ summary: '获取用户手机号' })
  @ApiBody({ type: MpAuthPhoneDto })
  async validatePhone(@Body() dto: MpAuthPhoneDto, @AuthUser() user: IAuthUser): Promise<string> {
    return await this.mpAuthService.getPhone(dto?.code ?? '', user?.uid);
  }

  @AllowAnon()
  @Post('user')
  @ApiOperation({ summary: '更新用户微信信息' })
  @ApiBody({ type: MpAuthUpdateUserInfoDto })
  async updateUserInfo(@Body() dto: MpAuthUpdateUserInfoDto, @AuthUser() user: IAuthUser) {
    await this.userService.updateWechatUserInfo(user?.uid, dto);
  }

  @Public()
  @Post('logout')
	@ApiOperation({ summary: '退出登录' })
  async logout(@AuthUser() user: IAuthUser, @AuthToken() token: string): Promise<void> {
    this.logger.debug(`logout wx user: ${user?.uid}`);

    if (!user || !token) {
      throw new BusinessException(ErrorEnum.UNAUTHORIZED);
    }

    await this.authService.clearLoginStatus(user, token);
  }
}
